<?php

/**
 * author:huhaiqin
 * time:2019-11-13 
 * feature:用户表逻辑实现
 */

namespace Common\Model;

use Think\Model;

class UsersModel extends Model
{
    /**
     * 2022.05.31 huhaiqn
     * 修改用户的一些基础信息
     * 支持修改realname，avatar，sex，nickname,birthday等
     * 2023.05.14  xqx 增加修改country
     * 2023.06.09 huhaiqin 出来了更新后的session变化
     */
    public function _update_user_base($post){
        $post['id'] = $post['id'] ? $post['id'] : $_SESSION['loginUser']['id'];
        if($post['id'] == ''){
            _apiReturn(0,'用户ID不能为空~');
        }
        $data = [];
        $data['id'] = $post['id'];
        if($post['sex']){
            $data['sex'] = $post['sex'];
        }
        if($post['avatar']){
            $data['avatar'] = $post['avatar'];
        }
        if($post['realname']){
            $data['realname'] = $post['realname'];
        }
        if($post['nickname']){
            $data['nickname'] = $post['nickname'];
        }
        if($post['birthday']){
            $data['birthday'] = $post['birthday'];
        }
        if($post['country']){
            $data['country'] = $post['country'];
        }
        //判断是否有需要修改的数据
        if(count($data) <= 1){
            _apiReturn(0,'缺少需要更新的用户数据~');
        }
        $data['update_time'] = time();
        if($this->save($data)){
            // unset($data['id']);
            //更新session
            if($_SESSION['loginUser']['id'] == $data['id']){
                foreach ($data as $key => $value) { 
                    $_SESSION['loginUser'][$key] = $value;
                } 
            }            
            _apiReturn(1,'success',$data);
        }else{
            _apiReturn(0,'用户信息更新失败~');
        }
    }

    /**
     * 满足基础的列表查询工作
     */
    public function _query($p = 1, $row = 10, $query = '')
    {
        $sql = "SELECT A.`id`,A.`username`,A.`mobile`,A.country,A.address,A.website,A.`email`,A.`nickname`,A.`realname`,A.`avatar`,A.`role`,A.`role_type`,A.`sex`,A.`status`,A.`create_time`,A.`update_time` FROM mini_users A WHERE 1=1 ";
        $sqlcount = "SELECT COUNT(DISTINCT A.`id`) AS tp_count FROM mini_users A WHERE 1=1 ";
        if ($query) {
            $sql .= $query;
            $sqlcount .= $query;
        }
        //order
        $total = $this->query($sqlcount);
        $data['page']['total'] = $total[0]['tp_count'];
        //处理删除最后一条数据的时候没有数据的bug,请求最后一页没有数据的bug
        if($data['page']['total']>0){
            if (floor(($data['page']['total'] + $row - 1) / $row) < $p) {
                $p = $p - 1;
            }
        }
        
        $sql .= " ORDER BY A.id desc ";
        $sql .= " LIMIT " . ($p - 1) * $row . "," . $row;
        $data['data'] = $this->query($sql);
        $data['page']['cur'] = $p;
        $data['page']['row'] = $row;
        return $data;
    }

    /**
     * 登录实现
     * 加上type的判断，有type表示传进来的密码是已经加密过的
     * 20200924，haiqin，保存session前，修改一下将字符串config转换成array
     * 2022.05.31，huhaiqin，加入登录的类型，加入区分是web端还是app端，如果是app端，不生产session
     */
    public function login($post = [],$client = 'web')
    {
        $username = $post['username'];
        $password = $post['password'];
        $type = $post['type']; //用来判断提交上来的密码是否加密
        if( !$type ){
            $password = md5($password);
        }

        if ($username == '') {
            _apiReturn(0, '用户名或手机号必须');
        }
        if ($password == '') {
            _apiReturn(0, '密码必须~');
        }

        //检测$username是否为手机号码
        if (check_phone($username)) {
            $map = [
                'mobile' => $username,
                'password' => $password
            ];
        } else {
            $map = [
                'username' => $username,
                'password' => $password
            ];
        }

        $user = $this->where($map)->find();
        if (!$user) {
            _apiReturn(0, '用户名（手机号）或密码错误~');
        } else {
            if($user['status'] == -1){
                _apiReturn(0, '该账号已被禁用');
            }
            unset($user['password']);
            $user['config'] = json_decode($user['config'],true); // 转一下config的格式
            if($client == 'web'){
                session('loginUser', $user); //登录状态写入session
            }
            $redirect = C('user.login_redirect'); //获取配置文件里面，不同用户登录成功之后的跳转地址
            _apiReturn(1, '登录成功', $user, $redirect[$user['role']]); //默认返回首页 
        }
    }

    /**
     * 注册实现
     * 2022.05.31 huhaiqin , 区分web端还是客户端使用，客户端下不生成session
     * 2023.05.10 xuqixiang 
     */
    public function reg($post = [],$client = 'web')
    {
        if (!$post['username']) {
            _apiReturn(0, '用户名必须~');
        }
        if (!$post['password']) {
            _apiReturn(0, '密码必须~');
        }else{
            $post['password'] = md5($post['password']);
        }

        if(!$post['email']){
            _apiReturn(0, '邮箱必须~');
        }
        
        $post['update_time'] = $post['create_time'] = time();
        
        $res = $this->_check_update_user($post); //检测用户名、邮箱是否已注册
        
        if($res){
            if($client == 'app'){
                $post['status'] = 0; //账户状态1表示正常，0表示邮箱未验证，-1表示禁用
            }
            if ($uid = $this->add($post)) {
                $user = $this->find($uid);
                unset($user['password']);
                $user['config'] = json_decode($user['config'],true); // 转一下config的格式
                if($client == 'web'){
                    session('loginUser', $user); //登录状态写入session
                }
                $redirect = C('user.login_redirect'); //获取配置文件里面，不同用户登录成功之后的跳转地址
                _apiReturn(1, '注册成功！', $user, $redirect[$user['role']]); //默认返回首页 
            } else {
                _apiReturn(0, '注册失败！');
            }
        }        
    }
   
    /**
     * 修改密码实现
     * 2023.06.26 xqx
     */
    public function repwd($oldpwd = '', $newpwd = '', $repwd = '', $uid = 0)
    {
        $uid = $uid == 0 ? get_uid() : $uid;
        //如果没有检测到uid，表示没有登录，不能修改密码
        if (!$uid) {
            _apiReturn(0, '请先登录~', [], '/user/login'); //返回一个url，需要跳转
        }
        if ($repwd != $newpwd) {
            _apiReturn(0, '重复密码不一致~');
        }
        if ($oldpwd == '' || $newpwd == '') {
            _apiReturn(0, '原密码与新密码必须~');
        }

        $check = $this->where(['id' => $uid, 'password' => md5($oldpwd)])->find(); //检测原密码是否正确
        if (!$check) {
            _apiReturn(0, '原密码错误，请检查~');
        }
        if ($this->save(['id' => $uid, 'password' => md5($newpwd), 'update_time' => time()])) {
            _apiReturn(1, '密码修改成功~');
        } else {
            _apiReturn(0, '系统错误，密码修改失败');
        }
    }

    /**
     * 重置密码实现
     */
    public function repassword($newpwd = '', $uid = 0)
    {
        $uid = $uid == 0 ? get_uid() : $uid;
        //如果没有检测到uid，表示没有登录，不能修改密码
        if (!$uid) {
            _apiReturn(0, '请先登录~', [], '/user/login'); //返回一个url，需要跳转
        }

        if ($newpwd == '') {
            _apiReturn(0, '密码必须~');
        }

        $check = $this->where(['id' => $uid, 'role' => "student"])->find(); //检测账号是否正确
        if (!$check) {
            _apiReturn(0, '找不到改学生');
        }
        if ($this->save(['id' => $uid, 'password' => md5($newpwd), 'update_time' => time()])) {
            _apiReturn(1, '密码重置成功~,新密码为111111');
        } else {
            _apiReturn(0, '系统错误，密码重置失败');
        }
    }

    /**
     * 找回密码实现/手机，邮箱
     */
    public function findpwd($post)
    {
        $res = $post;
        if (!$res['email']) {
            $where['mobile'] = $res['mobile'];
            $data = $this->where($where)->find();
            if (!$data) {
                _apiReturn(0, '该手机号尚未注册');
            }
        } else {
            $where['email'] = $res['email'];
            $data = $this->where($where)->find();
            if (!$data) {
                _apiReturn(0, '邮箱尚未绑定');
            }
        }

        $res['id'] = $data['id'];
        $res['update_time'] = time();
        $res['password'] = md5($res['password']);
        if ($this->save($res)) {
            _apiReturn(1, 'success');
        } else {
            _apiReturn(0, 'error');
        }
    }


    /**
     * 类自有函数，检测数据中是否可以合法添加用户
     * 如果id为0，表示执行的是添加操作，如果不是0，则表示执行的是修改操作
     * 20200916，haiqin，修补原来留下的bug
     */
    private function _check_update_user($data = [])
    {
        //检测用户名
        if ($data['username'] != '') {
            $user = $this->where(['username' => $data['username']])->find();
            if ($user) {
                if ($data['id'] != 0) {
                    if ($user['id'] != $data['id']) {
                        _apiReturn(0, '用户名已经存在，请换一个用户名~');
                    }
                } else {
                    _apiReturn(0, '用户名已经存在，请换一个用户名~');
                }
            }
        }
        //检测手机号码
        if ($data['mobile'] != '') {
            $user = $this->where(['mobile' => $data['mobile']])->find();
            if ($user) {
                if ($data['id'] != 0) {
                    if ($user['id'] != $data['id']) {
                        _apiReturn(0, '手机号码已经存在~');
                    }
                } else {
                    _apiReturn(0, '手机号码已经存在~');
                }
            }
        }
        //检测email
        if ($data['email'] != '') {
            
            $user = $this->where(['email' => $data['email']])->find();
            // _apiReturn(0,'111',$data);
            if ($user) {
                if ($data['id'] != 0) {
                    if ($user['id'] != $data['id']) {
                        _apiReturn(0, '邮箱已经被注册~');
                    }
                } else {
                    _apiReturn(0, '邮箱已经被注册~');
                }
            }
        }
        return true;
    }
   /**
     * 编辑账户
     * 用户名和手机号码密码必须,真实姓名必须
     * 20200916,haiqin,优化账户创建条件,支持创建教研员，支持创建学校管理员
     * 20200921,haiqin,支持创建教研员
     * 20200922,haiqin,如果手机号码存在，则需要检测手机号码，如果不存在，则不需要校验手机号码
     * 20200924,haiqin,当修改的事情，可以不存在username
     */
    public function edit_user($post)
    {
        $user = get_user(I('uid')); //这里只有在PC端登录的时候才能够添加教师账户
        if (!$user) {
            _apiReturn(0, '请先登录');
        }
        if ($user['role'] != 'admin') {
            _apiReturn(0, '对不起，您没有权限创建账户');
        }

        if (!$post['username'] && !$post['id']) {
            _apiReturn(0, '用户名必须~');
        }

        if (!$post['realname']) {
            _apiReturn(0, '真实姓名必须~');
        }


        if (!$post['password'] && !$post['id']) {
            $post['password'] = '123456'; //这里使用默认密码
            // _apiReturn(0, '密码必须~');
        }

        if($post['new_role']){
            $post['role'] = $post['new_role'];
        }

        $post['update_time'] = time();
        $data = $this->create($post); //数据封装一下
        $this->_check_update_user($data); //检测用户名、手机号码、邮箱是否能够使用

        if ($data['status'] == '') {
            $data['status'] = -1; //-1表示禁用
        }
        $data['config'] = json_encode($post['config'],JSON_UNESCAPED_UNICODE); //编码
        if ($data['id']) {
            if ($data['password'] == '') {
                unset($data['password']);
            } else {
                $data['password'] = md5($data['password']);
            }
           
            if ($this->save($data)) {
                  _apiReturn(1, 'success');
            } else {
                _apiReturn(0, 'error');
            }
        } else {
            $data['create_time'] = time();
            $data['password'] = md5($data['password']);
            $uid = $this->add($data);
            if ($uid) {
                _apiReturn(1, 'success');
            } else {
                _apiReturn(0, 'error');
            }
        }
    }

    /**
     * 删除的安全规则
     * 如果是教师用户，只有状态为-1（禁用）才能删除，并且，只能由管理员删除
     * 20200916,haiqin,加入学校管理员的删除限制
     */
    public function _del($ids)
    {
        if (count($ids) == 0) {
            _apiReturn(0, '缺少可操作的数据~');
        }
        $user = get_user(I('uid'));
        if (!$user) {
            _apiReturn(0, '检测不到当前用户');
        }
        if (!in_array($user['role'], ['admin'])) {
            //非管理员或教师用户没有删除账户的权限
            _apiReturn(0, '对不起，您没有该权限~');
        }
        $del_users = $this->where(['id' => ['in', $ids]])->select();
        //循环执行删除
        $check = true;
        $msg = '';
        foreach ($del_users as $u) {
            if ($u['status'] != -1) {
                $check = false;
                $msg = '请先禁用待删除账户,然后继续删除~'; //防止误删除
                break;
            }
            if ($user['role'] == 'admin') {
                //如果当前账户为超管账户
                if ($u['role'] == 'admin') {
                    if ($u['id'] != $user['id']) {
                        //自己不能删除
                        $this->where(['id' => $u['id'], 'status' => -1])->delete(); //删除该用户
                    } else {
                        $check = false;
                        $msg = '您没有权限删除该管理员~';
                        break;
                    }
                } else {
                    $this->where(['id' => $u['id'], 'status' => -1])->delete(); //删除该用户
                }
            }else {
                //这里处理教师用户的删除，教师用户能删除学生账户和家长账户，当然，为了防止误操作，也是需要将用户状态打为禁用才行
                $map = [
                    'id' => $u['id'],
                    'status' => -1,
                    'role' => ['in', ['student', 'parent']]
                ];
                $this->where($map)->delete(); //删除该用户
            }
        }
        if ($check) {
            _apiReturn(1, 'success');
        } else {
            _apiReturn(0, $msg);
        }
    }

    /**
     * 改变用户状态
     */
    public function change_status($ids = [], $status = 1)
    {
        if (count($ids) == 0) {
            _apiReturn(0, '缺少可操作的数据~');
        }
        if (!in_array($status, [-1, 1])) {
            //限制一下状态值
            _apiReturn(0, '状态值匹配不到~');
        }
        $user = get_user(I('uid'));
        if (!$user) {
            _apiReturn(0, '检测不到当前用户');
        }
        if (!in_array($user['role'], ['admin', 'teacher'])) {
            //非管理员或教师用户没有删除账户的权限
            _apiReturn(0, '对不起，您没有该权限~');
        }

        $map = [
            'id' => ['in', $ids]
        ];
        $map['role'] = $user['role'] == 'admin' ? ['in', ['teacher', 'student', 'parent']] : ['in', ['student', 'parent']]; //限制不同角色的用户能够修改状态的用户角色范围
        $data = [
            'update_time' => time(),
            'status' => $status
        ];
        if ($this->where($map)->save($data)) {
            _apiReturn(1, 'success');
        } else {
            _apiReturn(0, 'error,' . $this->getError());
        }
    }

    /**
     * 20201124,haiqin
     * 通过手机号码重置密码
     */
    public function resetpwd_by_mobile($mobile='',$password=''){
        if($mobile == ''){
            _apiReturn(0,'手机号码不能为空~');
        }
        if($password == ''){
            _apiReturn(0,'密码不能为空~');
        }
        $user = $this->where(['mobile' => $mobile])->find();
        if(!$user){
            _apiReturn(0,'该手机号码尚未注册');
        }
        $data = [
            'id' => $user['id'],
            'password' => md5($password),
            'update_time' => time()
        ];
        if($this->save($data)){
            //执行登录
            unset($user['password']);
            $user['config'] = json_decode($user['config'],true); // 转一下config的格式
            session('loginUser', $user); //登录状态写入session
            $redirect = C('user.login_redirect'); //获取配置文件里面，不同用户登录成功之后的跳转地址
            _apiReturn(1, '密码修改成功，正在跳转', '', $redirect[$user['role']]); //默认返回首页 
        }else{
            _apiReturn(0,'密码修改失败~');
        }
    }  

    /**
     * 2022.05.24 huhaiqin
     * 修改用户头像
     */
    public function _change_avatar($uid = 0, $avatar = ''){
        if($uid == 0){
            $uid = $_SESSION['loginUser']['id']; //如果用户ID为0，读取session里面的用户ID
        }
        if(!$uid){
            _apiReturn(0,'用户ID不能为空~');
        }
        $data = [
            'id' => $uid,
            'avatar' => $avatar,
            'update_time' => time()
        ];
        if($this->save($data)){
            if($_SESSION['loginUser']){
                $_SESSION['loginUser']['avatar'] = $avatar;
            }
            _apiReturn(1,'success',$avatar);
        }else{
            _apiReturn(0,'头像修改失败~');
        }
    }


    /**
     * 2023.05.15  xqx
     * 修改密码
     */
    public function _repwd_from_app($post){
        $check = $this->where(['id' => $post['id'], 'password' => md5($post['password']['old'])])->find(); //检测原密码是否正确
        if (!$check) {
            _apiReturn(0, '原密码错误，请检查~');
        }
        if ($this->save(['id' => $post['id'], 'password' => md5($post['password']['newpwd']), 'update_time' => time()])) {
            _apiReturn(1, '密码修改成功~');
        } else {
            _apiReturn(0, '密码修改失败');
        }
    }

    /**
     * 修改经销商地址信息
     * 2023.06.26 xqx
     */
    public function edit_address($address = '',$country = '', $uid = 0)
    {
        $uid = $uid == 0 ? get_uid() : $uid;
        //如果没有检测到uid，表示没有登录，不能修改
        if (!$uid) {
            _apiReturn(0, '请先登录~', [], '/user/login'); //返回一个url，需要跳转
        }

        if ($this->save(['id' => $uid, 'address' => $address, 'country' => $country , 'update_time' => time()])) {
            $_SESSION['loginUser']['address'] = $address;
            $_SESSION['loginUser']['country'] = $country;
            _apiReturn(1, '地址修改成功~');
        } else {
            _apiReturn(0, '系统错误，地址修改失败');
        }
    }

    /**
     * 修改经销商介绍信息
     * 2023.06.26 xqx
     */
    public function edit_selfinfo($info = '', $uid = 0)
    {
        $uid = $uid == 0 ? get_uid() : $uid;
        //如果没有检测到uid，表示没有登录，不能修改
        if (!$uid) {
            _apiReturn(0, '请先登录~', [], '/user/login'); //返回一个url，需要跳转
        }
        
        if ($this->save(['id' => $uid, 'info' => $info, 'update_time' => time()])) {
            $_SESSION['loginUser']['info'] = $info;
            _apiReturn(1, '修改成功~');
        } else {
            _apiReturn(0, '系统错误，修改失败');
        }
    }
}
